package zhjb.temp.db;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import zhjb.temp.db.annotation.Column;
import zhjb.temp.db.annotation.Id;
import zhjb.temp.db.annotation.Table;
import zhjb.temp.db.test.Test;

/**
 * 数据库配置上下文
 * 
 * @author zhangjianbig@msn.com
 * 
 */
public class Context {
	private static Map<String, VTable> context = new HashMap<String, VTable>();

	/**
	 * 注册一个映射类
	 * 
	 * @param clazz
	 * @throws Exception
	 */
	public static void registe(final Class clazz) throws Exception {
		Table table = (Table) clazz.getAnnotation(Table.class);
		if (table != null) {
			String tableName = table.name();
			VTable tableConTable = new VTable();
			tableConTable.setClazz(clazz);
			tableConTable.setName(tableName);
			tableConTable.setMap(new HashMap<String, VField>());
			Method[] methods = clazz.getDeclaredMethods();
			for (Method m : methods) {
				String mName = m.getName();
				if (mName.startsWith("get") || mName.startsWith("is")) {
					Column column = (Column) m.getAnnotation(Column.class);
					if (column != null) {
						String cname = column.name();
						if (m.getAnnotation(Id.class) != null) {
							tableConTable.setIdName(cname);
						}
						VField vField = new VField();
						vField.setName(cname);
						vField.setGetMethod(m);// get方法
						String typeName = m.getReturnType().getName().toLowerCase();
						/*
						 * 寻找映射类型，目前支持有限
						 */
						int type = VType.STRING;
						if (typeName.equals("java.lang.string")) {
							type = VType.STRING;
						} else if (typeName.equals("int")) {
							type = VType.INT;
						} else if (typeName.equals("double")) {
							type = VType.DOUBLE;
						} else if (typeName.equals("float")) {
							type = VType.FLOAT;
						} else if (typeName.equals("long")) {
							type = VType.LONG;
						} else if (typeName.equals("short")) {
							type = VType.SHORT;
						} else if (typeName.equals("boolean")) {
							type = VType.BOOLEAN;
						} else if (typeName.equals("char")) {
							type = VType.CHAR;
						} else if (typeName.equals("java.util.date") || typeName.equals("java.sql.date")) {
							type = VType.DATE;
						}
						vField.setType(type);
						/*
						 * 找set方法
						 */
						String setName = null;
						if (mName.startsWith("get")) {
							setName = "set" + mName.substring(3);
						} else {
							setName = "set" + mName.substring(2);
						}
						Method setMethod = null;
						if (type == VType.BOOLEAN) {
							setMethod = clazz.getDeclaredMethod(setName, Boolean.class);
						} else if (type == VType.CHAR) {
							setMethod = clazz.getDeclaredMethod(setName, Character.class);
						} else if (type == VType.DATE) {
							setMethod = clazz.getDeclaredMethod(setName, java.util.Date.class);
						} else if (type == VType.DOUBLE) {
							setMethod = clazz.getDeclaredMethod(setName, Double.class);
						} else if (type == VType.FLOAT) {
							setMethod = clazz.getDeclaredMethod(setName, Float.class);
						} else if (type == VType.INT) {
							setMethod = clazz.getDeclaredMethod(setName, Integer.class);
						} else if (type == VType.LONG) {
							setMethod = clazz.getDeclaredMethod(setName, Long.class);
						} else if (type == VType.SHORT) {
							setMethod = clazz.getDeclaredMethod(setName, Short.class);
						} else if (type == VType.STRING) {
							setMethod = clazz.getDeclaredMethod(setName, String.class);
						}
						vField.setSetMethod(setMethod);
						if (!tableConTable.getMap().containsKey(cname)) {
							tableConTable.getMap().put(cname, vField);
						} else {
							throw new Exception("字段重复映射:" + cname);
						}
					}
				}
			}
			context.put(clazz.getName(), tableConTable);
		} else {
			throw new Exception("没有映射表：" + clazz.getName());
		}
	}

	public static VTable getVTable(Class clazz) {
		return context.get(clazz.getName());
	}

	public static void main(String[] args) {
		try {
			registe(Test.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
